﻿#if !PURE_CLR

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace Krile.Imported.Controls
{
    /// <summary>
    /// Hotkey コントロール
    /// </summary>
    /// from http://azumaya.s101.xrea.com/wiki/index.php?%B3%D0%BD%F1%2FC%A2%F4%2FC%A2%F4%A4%C7%A5%DB%A5%C3%A5%C8%A5%AD%A1%BC%A5%B3%A5%F3%A5%C8%A5%ED%A1%BC%A5%EB%A4%F2%BA%EE%A4%EB
    public class HotkeyControl : System.Windows.Forms.UserControl
    {
        #region Hotkey API ラップクラス
        class WinApi
        {
            // 多分無意味です
            static WinApi()
            {
                InitCommonControls();
            }
            [DllImport("user32.dll")]
            public static extern int SendMessage(
                IntPtr h, int m, IntPtr w, IntPtr l);

            [DllImport("comctl32.dll")]
            public static extern bool InitCommonControls();
            public const int HKCOMB_NONE = 0x0001;
            public const int HKCOMB_S = 0x0002;
            public const int HKCOMB_C = 0x0004;
            public const int HKCOMB_A = 0x0008;
            public const int HKCOMB_SC = 0x0010;
            public const int HKCOMB_SA = 0x0020;
            public const int HKCOMB_CA = 0x0040;
            public const int HKCOMB_SCA = 0x0080;

            public const int HKM_SETHOTKEY = (0x400 + 1);
            public const int HKM_GETHOTKEY = (0x400 + 2);
            public const int HKM_SETRULES = (0x400 + 3);

            public const int HOTKEYF_SHIFT = 0x01;
            public const int HOTKEYF_CONTROL = 0x02;
            public const int HOTKEYF_ALT = 0x04;
            //public const int HOTKEYF_EXT     = 0x80;
            public const int HOTKEYF_EXT = 0x08;
        }
        #endregion

        private System.ComponentModel.Container components = null;
        Keys m_hotkey;
        public HotkeyControl()
        {
            components = new System.ComponentModel.Container();
            // .NET はコントロールを描画しません。
            SetStyle(ControlStyles.UserPaint, false);
        }

        /// <summary>
        /// 使用されているリソースに後処理を実行します。
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
                components.Dispose();
            base.Dispose(disposing);
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ClassName = "msctls_hotkey32";
                return cp;
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
        }


        /// <summary>
        /// ホットキーの値を取得または設定します。
        /// </summary>
        public Keys Hotkey
        {
            get
            {
                if (this.IsHandleCreated)
                {
                    int k = WinApi.SendMessage(
                        this.Handle, WinApi.HKM_GETHOTKEY,
                        IntPtr.Zero, IntPtr.Zero);
                    Keys ret = (Keys)(k & 0xff);
                    k = k >> 8;
                    if ((k & WinApi.HOTKEYF_ALT) != 0)
                        ret |= Keys.Alt;
                    if ((k & WinApi.HOTKEYF_CONTROL) != 0)
                        ret |= Keys.Control;
                    if ((k & WinApi.HOTKEYF_SHIFT) != 0)
                        ret |= Keys.Shift;
                    return ret;
                }
                else
                {
                    return this.m_hotkey;
                }
            }
            set
            {
                if (this.IsHandleCreated)
                {
                    int k = 0;
                    if ((value & Keys.Alt) != 0)
                        k |= WinApi.HOTKEYF_ALT;
                    if ((value & Keys.Control) != 0)
                        k |= WinApi.HOTKEYF_CONTROL;
                    if ((value & Keys.Shift) != 0)
                        k |= WinApi.HOTKEYF_SHIFT;
                    WinApi.SendMessage(this.Handle, WinApi.HKM_SETHOTKEY,
                        (IntPtr)(k << 8 | ((int)value & 0xffff)), IntPtr.Zero);
                }
                else
                {
                    this.m_hotkey = value;
                }
            }
        }
    }
}
#endif